﻿using JESAI.Application.Abstractions.Admin;
using JESAI.Application.Abstractions.Admin.Dtos.Role;
using JESAI.Application.Abstractions.Admin.Dtos.RoleApi;
using JESAI.Application.Abstractions.Admin.Dtos.RoleMenu;
using JESAI.Application.Abstractions.Admin.Dtos.User;
using JESAI.Application.Abstractions.Dtos;
using JESAI.Application.Abstractions.Sys.Dtos;
using JESAI.AutoMapper.ObjectMapping;
using JESAI.Core.Attributes;
using JESAI.Core.Extensions;
using JESAI.Platform.Domain.Admin.Entities;
using JESAI.Platform.Domain.Admin.Repositories;
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JESAI.Application.Service.Admin
{
    [AppService]
    public class RoleService : IRoleService
    {
        private readonly IRoleRepository _roleRepository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly IRoleMenuRepository _roleMenuRepository;
        private readonly IRoleApiRepository _roleApiRepository;
        public RoleService(IRoleRepository roleRepository, IRoleMenuRepository roleMenuRepository, IRoleApiRepository roleApiRepository, IUserRoleRepository userRoleRepository)
        {
            _roleRepository = roleRepository;
            _roleMenuRepository = roleMenuRepository;
            _roleApiRepository = roleApiRepository;
            _userRoleRepository = userRoleRepository;
        }

        public void DeleteRole(long roleId)
        {
            _roleRepository._DbQueryable.Context.Ado.BeginTran();
            try
            {
                // 删除角色菜单权限
                _roleMenuRepository.AsDeleteable().Where(f => f.RoleId == roleId).ExecuteCommand();
                // 删除角色接口权限
                _roleApiRepository.AsDeleteable().Where(f => f.RoleId == roleId).ExecuteCommand();
                // 删除用户角色关系
                _userRoleRepository.AsDeleteable().Where(f => f.RoleId == roleId).ExecuteCommand();
                // 删除角色
                _roleRepository.AsDeleteable().Where(f => f.Id == roleId).ExecuteCommand();
                _roleRepository._DbQueryable.Context.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                _roleRepository._DbQueryable.Context.Ado.RollbackTran();
                throw new Exception("事务执行失败", ex);
            }
        }

        public void DeleteRoles(long[] roleId)
        {
            _roleRepository._DbQueryable.Context.Ado.BeginTran();
            try
            {
                // 删除角色菜单权限
                _roleMenuRepository.AsDeleteable().Where(f => roleId.Contains(f.RoleId)).ExecuteCommand();
                // 删除角色接口权限
                _roleApiRepository.AsDeleteable().Where(f => roleId.Contains(f.RoleId)).ExecuteCommand();
                // 删除用户角色关系
                _userRoleRepository.AsDeleteable().Where(f => roleId.Contains(f.RoleId)).ExecuteCommand();
                // 删除角色
                _roleRepository.AsDeleteable().Where(f => roleId.Contains(f.Id)).ExecuteCommand();
                _roleRepository._DbQueryable.Context.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                _roleRepository._DbQueryable.Context.Ado.RollbackTran();
                throw new Exception("事务执行失败", ex);
            }
        }

        public List<RoleDto> QueryAllRoles(QueryRolesInput input)
        {
            var modelList = _roleRepository._DbQueryable
                                 .WhereIF(!input.PlatformKey.IsEmpty(), it => it.PlatformKey == input.PlatformKey)
                                 .ToList();
            return modelList.MapTo<List<RoleDto>>();
        }

        public List<RoleApiDto> QueryApiByRoleId(int roleId)
        {
            var modeList = _roleApiRepository._DbQueryable.Where(p => p.RoleId == roleId).ToList();
            return modeList.MapTo<List<RoleApiDto>>();
        }

        public List<RoleMenuDto> QueryMenuByRoleId(int roleId)
        {
            var modeList = _roleMenuRepository._DbQueryable.Where(p => p.RoleId == roleId).ToList();
            return modeList.MapTo<List<RoleMenuDto>>();
        }

        public RoleDto QueryRoleInfo(int roleId)
        {
            var roleInfo = _roleRepository._DbQueryable.Where(it => it.Id == roleId).First();
            return roleInfo.MapTo<RoleDto>();
        }

        public BasePageOutput<List<QueryRoleDto>> QueryRoles(QueryRolesPageInput input)
        {
            var totalNumber = 0;
            var modelList = _roleRepository._DbQueryable
                               .Where(it => it.IsDel == false)
                               .WhereIF(!input.PlatformKey.IsEmpty(), it => it.PlatformKey == input.PlatformKey)
                               .WhereIF(!input.Name.IsEmpty(), it => it.Name == input.Name)
                               .WhereIF(!input.Key.IsEmpty(), it => it.Key == input.Key)
                               .ToPageList(input.PageIndex, input.PageSize, ref totalNumber);

            return new BasePageOutput<List<QueryRoleDto>> { Data = modelList.MapTo<List<QueryRoleDto>>(), CurrentPage = input.PageIndex, Total = totalNumber };
        }

        public void UpdateOrInsert(SetRoleInput input)
        {
            try
            {
                _roleRepository.AsQueryable().Context.Ado.BeginTran();

                #region 基础信息更新
                var model = input.MapTo<RoleModel>();
                if (model.Id > 0)
                {
                    model.UpdateTime = DateTime.Now;
                    _roleRepository.AsUpdateable(model)
                                   .IgnoreColumns(it => new { it.PlatformKey, it.CreateTime, it.IsSys })
                                   .ExecuteCommand();
                }
                else
                {
                    model.CreateTime = DateTime.Now;
                    model.IsDel = false;
                    model.Id = _roleRepository.AsInsertable(model).ExecuteReturnIdentity();
                }
                #endregion

                #region 菜单权限
                // 用户角色操作
                List<RoleMenuModel> roleMenuList = new List<RoleMenuModel>();
                foreach (var id in input.MenuIdList)
                {
                    // 防止重复数据
                    if (!roleMenuList.Exists(it => it.MenuId == id))
                    {
                        roleMenuList.Add(new RoleMenuModel
                        {
                            MenuId = id,
                            RoleId = model.Id
                        });
                    }
                }
                // 删除用户当前角色
                _roleMenuRepository.AsDeleteable().Where(f => f.RoleId == model.Id).ExecuteCommand();
                // 添加用户角色
                if (roleMenuList.Count > 0)
                    _roleMenuRepository.AsInsertable(roleMenuList).ExecuteCommand();
                #endregion

                #region 接口权限
                // 用户角色操作
                List<RoleApiModel> roleApiList = new List<RoleApiModel>();
                foreach (var id in input.ApiIdList)
                {
                    // 防止重复数据
                    if (!roleApiList.Exists(it => it.ApiId == id))
                    {
                        roleApiList.Add(new RoleApiModel
                        {
                            ApiId = id,
                            RoleId = model.Id
                        });
                    }
                }
                // 删除用户当前角色
                _roleApiRepository.AsDeleteable().Where(f => f.RoleId == model.Id).ExecuteCommand();
                // 添加用户角色
                if (roleApiList.Count > 0)
                    _roleApiRepository.AsInsertable(roleApiList).ExecuteCommand();
                #endregion

                _roleRepository.AsQueryable().Context.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                _roleRepository.AsQueryable().Context.Ado.RollbackTran();
                throw new Exception("事务执行失败", ex);
            }
        }
    }
}
